home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / idioms.lha / idioms / 5num.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  4KB  |  175 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. #include <iostream.h>
  7. #include <stdio.h>
  8.  
  9. struct BaseConstructor { BaseConstructor(int=0) { } };
  10.  
  11. class Number {
  12. public:
  13.     Number(BaseConstructor);
  14.     Number();
  15.     Number(double d);
  16.     Number(double rpart, double ipart);
  17.     Number operator=(Number & n) {
  18.     printf("Number::operator=(Number&)\n");
  19.         n.rep->referenceCount++;
  20.         if (--rep->referenceCount == 0) delete rep;
  21.         rep = n.rep;
  22.         return *this;
  23.     }
  24.     void redefine(Number *n) {
  25.     printf("Number::redefine(Number*)\n");
  26.         if (--rep->referenceCount == 0) delete rep;
  27.         rep = n;
  28.     }
  29.     Number(Number & n) {
  30.     printf("Number::Number(Number&)\n");
  31.         n.rep->referenceCount++;
  32.         rep = n.rep;
  33.     }
  34.     virtual ostream& operator<<(ostream &s) {
  35.     printf("Number::operator<<(ostream&)\n");
  36.         return rep->operator<<(s);
  37.     }
  38.     virtual Number operator+(Number &n) {
  39.     printf("Number::operator+(Number&)\n");
  40.         return rep->operator+(n);
  41.     }
  42.     virtual Number complexAdd(Number &n) {
  43.     printf("Number::complexAdd(Number&)\n");
  44.         return rep->complexAdd(n);
  45.     }
  46.     virtual Number doubleAdd(Number &n) {
  47.     printf("Number::doubleAdd(Number&)\n");
  48.         return rep->doubleAdd(n);
  49.     }
  50. private:
  51.     union {
  52.         Number *rep;
  53.         short referenceCount;
  54.     };
  55. };
  56.  
  57. class Complex: public Number {
  58. friend class RealNumber;
  59. public:
  60.     Complex(double d, double e): Number(BaseConstructor()) {
  61.     printf("Complex::Complex(double, double)\n");
  62.         rpart = d; ipart = e;
  63.     }
  64.     Complex(const Complex &c): rpart(c.rpart), ipart(c.ipart) { }
  65.     Number operator+(Number &num) {
  66.     printf("Complex::operator+(Number&)\n");
  67.         Number n = num.complexAdd(*this);
  68.         return n;
  69.     }
  70.     Number complexAdd(Number &n);
  71.     Number doubleAdd(Number &n);
  72.     ostream& operator<<(ostream& o) {
  73.         o << "Complex(" << rpart << "," << ipart << ")";
  74.         return o;
  75.     }
  76. private:
  77.     double rpart, ipart;
  78. };
  79.  
  80. class RealNumber: public Number {
  81. friend Complex;
  82. public:
  83.     RealNumber(double d): Number(BaseConstructor()) {
  84.     printf("RealNumber::RealNumber(double)\n");
  85.         r = d;
  86.     }
  87.     RealNumber(const RealNumber &R): r(R.r) { }
  88.     Number operator+(Number &num) {
  89.     printf("RealNumber::operator+(Number&)\n");
  90.         Number newnum = num.doubleAdd(*this);
  91.         return newnum;
  92.     }
  93.     Number complexAdd(Number &n);
  94.     Number doubleAdd(Number &n) {
  95.     printf("RealNumber::doubleAdd(Number&)\n");
  96.         Number retval;
  97.         RealNumber *c1 = new RealNumber(*this);
  98.         RealNumber *c2 = (RealNumber*)&n;
  99.         c1->r += c2->r;
  100.         retval.redefine(c1);
  101.         return retval;
  102.     }
  103.     ostream& operator<<(ostream& o) {
  104.     printf("RealNumber::operator<<(ostream&)\n");
  105.         o << "Float(" << r << ")";
  106.         return o;
  107.     }
  108. private:
  109.     double r;
  110. };
  111.  
  112. ostream& operator<<(ostream&o, Number n) {
  113.     Number *np = &n;
  114.     return np->operator<<(o);
  115. }
  116.  
  117. Number::Number(BaseConstructor) {
  118.     printf("Number::Number(BaseConstructor)\n");
  119.     referenceCount = 1;
  120. }
  121.  
  122. Number::Number() {
  123.     printf("Number::Number()\n");
  124.     rep = new RealNumber(0.0);
  125. }
  126.  
  127. Number::Number(double d) {
  128.     printf("Number::Number(double)\n");
  129.     rep = new RealNumber(d);
  130. }
  131.  
  132. Number::Number(double d, double e) {
  133.     printf("Number::Number(double,double)\n");
  134.     rep = new Complex(d, e);
  135. }
  136.  
  137. Number Complex::complexAdd(Number &n) {
  138.     printf("Number::complexAdd(Number&)\n");
  139.     Number retval;
  140.     Complex *c1 = new Complex(*this);
  141.     Complex *c2 = (Complex*)&n;
  142.     c1->rpart += c2->rpart;
  143.     c1->ipart += c2->ipart;
  144.     retval.redefine(c1);
  145.     return retval;
  146. }
  147.  
  148. Number Complex::doubleAdd(Number &n) {
  149.     printf("Complex::doubleAdd(Number&)\n");
  150.     Number retval;
  151.     Complex *c1 = new Complex(*this);
  152.     RealNumber *c2 = (RealNumber*)&n;
  153.     c1->rpart += c2->r;
  154.     retval.redefine(c1);
  155.     return retval;
  156. }
  157.  
  158. Number RealNumber::complexAdd(Number &n) {
  159.     printf("RealNumber::complexAdd(Number&)\n");
  160.     Number retval;
  161.     Complex *c1 = new Complex(r, 0);
  162.     Complex *c2 = (Complex*)&n;
  163.     c1->rpart += c2->rpart;
  164.     c1->ipart += c2->ipart;
  165.     retval.redefine(c1);
  166.     return retval;
  167. }
  168.  
  169. int main() {
  170.     Number a = Number(1.0, 1.0);
  171.     Number b = 2.0;
  172.     Number c = a + b;
  173.     cout << "a = " << a << ", b = " << b << ", c = " << c << "\n";
  174. }
  175.